#include "mqtthandler.h"
#include <QTimer>
#include <qmqtt_client.h>

#define TOPIC_DATA_UP       "/app/data/up"    // 主题：数据上传
#define TOPIC_DATA_DOWN     "/app/data/down"  // 主题：数据下载
#define TOPIC_CTL_UP        "/app/control/up" // 主题：控制上传
#define TOPIC_CTL_DOWN      "/app/control/down" // 主题：控制下载

MqttHandler::MqttHandler(QObject *parent) : QObject(parent)
{
    client = new QMQTT::Client();  // 创建MQTT客户端实例
    client->setClientId("home-app");  // 设置客户端ID

    // 连接信号和槽函数
    connect(client, SIGNAL(connected()), this, SLOT(doConnected()));
    connect(client, SIGNAL(subscribed(QString, quint8)), this, SLOT(doSubscribed(QString, quint8)));
    connect(client, SIGNAL(received(QMQTT::Message)), this, SLOT(doDataReceived(QMQTT::Message)));
}

void MqttHandler::connectToHost()
{
    client->connectToHost();  // 连接到MQTT服务器

    // 3秒后检测连接状态
    QTimer::singleShot(3000, this, SLOT(detectState()));
}

void MqttHandler::detectState()
{
    int state = client->connectionState();  // 获取连接状态
    if (state != 2)  // 检查连接状态是否为已连接（状态码为2）
    {
        qDebug() << "mqtt connect error";  // 如果不是已连接状态，则输出错误信息
    }
}

/**
 * @brief 连接成功后订阅相关主题
 */
void MqttHandler::doConnected()
{
    qDebug() << "connect ok";  // 输出连接成功信息
    client->subscribe(TOPIC_DATA_UP);  // 订阅数据上传主题
    client->subscribe(TOPIC_CTL_UP);   // 订阅控制上传主题
}

void MqttHandler::doSubscribed(const QString &topic, const quint8 qos)
{
    qDebug() << "subscribed ok, topic=" << topic;  // 输出订阅成功的信息
}

void MqttHandler::doDataReceived(QMQTT::Message message)
{
    qDebug() << "topic=" << QString(message.topic());  // 输出接收到的消息主题
    qDebug() << "payload=" << QString(message.payload());  // 输出接收到的消息负载

    // 根据消息主题处理不同的业务逻辑
    if (message.topic() == TOPIC_DATA_UP)
    {
        qDebug() << "data up topic";  // 数据上传主题
        emit dataUpSignal(message.payload());  // 发送数据上传信号
    }
    else if (message.topic() == TOPIC_CTL_UP)
    {
        qDebug() << "ctrl up topic";  // 控制上传主题
        emit ctrlUpSignal(message.payload());  // 发送控制上传信号
    }

}

quint16 MqttHandler::publish(const QMQTT::Message &message)
{
    client->publish(message);  // 发布消息
}
